在文章系列的尾聲,我們大致複習一下究竟什麼是 FP 呢?先前我們曾經提到過,透過 FP 設計模式產出的程式碼會有以下特色:
以上這些特色大部分都是為了讓我們的程式碼更好閱讀、維護、再次利用,所以我們花了大部分的時間來理解 JavaScript 這門語言的特色,及我們可以在 JavaScript 中導入怎麼樣的 FP 工具,例如:純函式、柯里化、高階函式、複合函式等概念,來幫助我們完成這麼目標。
看到這邊各位可能會很疑惑:「FP 難道就只有這樣嗎?」
當然不止!如果你閱讀其他相關的書籍或是文章,可能會知道有一些 FP 特有的特性,像是:遞迴函式、Functor 、Applicative、 Monads 等著名的特色本文都沒有提到,就讓我們來聊聊為什麼我並沒有在這裡提到這些概念的原因。
大家知道 JavaScript 其實是一門歷史悠久的程式語言,再經過各式各樣的演進後,我們已經有許多非常好用、可讀性也很不錯的工具,我們有各式各樣的迴圈 API 可以使用。
其中更有能協助避開副作用、及意外改動到資料結構的工具,像是我們在本文中大量使用到 map
、filter
與 reduce
方法,這也是為什麼明明 FP 宣稱遞迴是比迴圈更好的工具,但我們卻沒有特別提及,比起一些沒有迴圈的語言,JavaScript 好像沒有一定要使用遞迴函式的理由。
另外一個我們不繼續討論下去的原因在於,畢竟 FP 是基於一個「數學理論」所延伸出來的「電腦科學理論」,繼續深入不免要了解一些有關於數學理論的概念。
如果你跟我一樣是一個數學很差的人,對於演算不是這麼有興趣,要繼續深入更複雜的函式應用就必須花更多的時間了解 lambda 演算法、或是甚至是範疇論(Category theory)的內容,這就讓 FP 變得沒那麼有趣了一點。
好啦,說實話是看到後頭我自己也看的不是很懂,連要舉例都有困難,於是舉白旗暫時投降,希望未來等開發經驗更足時,能對 FP 有更深一層的認識。
如果只是想要初步認識 FP 這個設計模式,或是想更深入了解 JavaScript 函式及資料結構的一些特性,我相信目前的內容已經很足夠一個剛開始使用 JavaScript 開發的新手來閱讀。
你甚至不需要很懂其所以然,就可以透過第三方函式庫,導入一些維護性高的 FP 函式來使用,或是輕鬆的透過複合函式、高階函式,或是將函式柯里化,讓我們的程式碼能被拆分為更小的單位來使用。
當然,如果後續對於 FP 進行更深入的了解,我非常推薦閱讀由 Eric Elliott 所撰寫 《Composing Software: An Exploration of Functional Programming and Object Composition in JavaScript》一書,作者使用非常簡單易懂的方式帶領讀者一步步理解 FP 的設計理念,在本文中也引用不少內容。
在這系列的文章中,我們沒有特別針對目前台灣主流的的三大框架進行討論,但若想要知道在框架中去實作 FP ,可以透過 React.js 這個框架進行開發。
在 React 中,我們使用 JSX 搭配 Functional Component ,也就是透過函式封裝元件:
import React from 'react';
export const Component = () => (
<div>我是一個 React Functional 元件</div>
);
在 React 中,也提供了許多稱為 Hook 的 API ,讓我們可以針對網頁的生命週期,或是一些進階的操作進行管理,而這些 API 就好比一個一個的鉤子,當我們需要它時,再進行引入、掛到指定的元件上,是不是非常典型 FP 的管理方式呢?
而在中大型專案需要進行複雜的狀態管理時,我們還會使用 Redux 這個工具,來進行狀態的統一管理,其中就使用大量的 reducer
的概念來優化 React 進行狀態管理的效能。
所以,如果你早就是一個 reduce()
、map()
、filter()
的愛用者,或是本來就已經使用 React 這個框架進行網頁的開發,其實早就在自己不知道的狀況下使用了 FP 這個設計模式了!
最後的最後,到了文章的尾聲,希望這系列的文章,可以帶給跟我一樣剛開始接觸 FP 的朋友們,一點粗淺的認識,謝謝你們閱讀到這裡。
在下一個章節中,想要用一點篇幅來跟大家分享一些非技術、寫這次鐵人賽的後記心得,那麼我們就下一個章節見吧!